using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using System.Windows.Shapes;

namespace GameOverlayWPF.Services
{
    /// <summary>
    /// 企业级UI交互动画服务 - 提供极致丝滑的界面交互体验
    /// 包括卡片加载、模式切换、筛选器弹出等企业级动画效果
    /// </summary>
    public class UIInteractionService
    {
        private static UIInteractionService _instance;
        private static readonly object _lockObject = new object();
        
        // 动画参数 - 经过精心调优的企业级参数
        private const int STAGGER_DELAY = 50;           // 交错动画延迟(ms)
        private const int CARD_LOAD_DURATION = 300;     // 卡片加载动画时长
        private const int MODE_SWITCH_DURATION = 400;   // 模式切换动画时长
        private const int FILTER_POPUP_DURATION = 250;  // 筛选器弹出时长
        private const int LOADING_PULSE_DURATION = 1200; // 加载脉冲时长
        
        // 缓动函数 - 企业级缓动效果
        private static readonly IEasingFunction CardLoadEasing = new BackEase 
        { 
            EasingMode = EasingMode.EaseOut, 
            Amplitude = 0.25 
        };
        
        private static readonly IEasingFunction ModeSwitchEasing = new CubicEase 
        { 
            EasingMode = EasingMode.EaseInOut 
        };
        
        private static readonly IEasingFunction FilterPopupEasing = new QuinticEase 
        { 
            EasingMode = EasingMode.EaseOut 
        };

        public static UIInteractionService Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_lockObject)
                    {
                        if (_instance == null)
                            _instance = new UIInteractionService();
                    }
                }
                return _instance;
            }
        }

        private UIInteractionService() { }

        #region 卡片加载动画

        /// <summary>
        /// 卡片交错加载动画 - 企业级瀑布流效果
        /// </summary>
        /// <param name="listBox">目标ListBox</param>
        /// <param name="useStagger">是否使用交错效果</param>
        /// <returns>异步任务</returns>
        public async Task AnimateCardLoadingAsync(ListBox listBox, bool useStagger = true)
        {
            if (listBox?.Items == null) return;

            await listBox.Dispatcher.InvokeAsync(async () =>
            {
                var containers = new List<ListBoxItem>();
                
                // 获取所有可见的ListBoxItem容器
                for (int i = 0; i < listBox.Items.Count; i++)
                {
                    var container = listBox.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem;
                    if (container != null)
                    {
                        containers.Add(container);
                        PrepareCardForAnimation(container);
                    }
                }

                if (!containers.Any()) return;

                // 创建交错动画
                var animationTasks = new List<Task>();
                for (int i = 0; i < containers.Count; i++)
                {
                    var container = containers[i];
                    var delay = useStagger ? i * STAGGER_DELAY : 0;
                    
                    var task = AnimateCardAppearance(container, delay);
                    animationTasks.Add(task);
                }

                await Task.WhenAll(animationTasks);
            });
        }

        private void PrepareCardForAnimation(FrameworkElement element)
        {
            // 只设置透明度，不改变卡片大小
            element.Opacity = 0;
            // 保持原有的RenderTransform，只添加轻微的位移效果
            if (element.RenderTransform == null || element.RenderTransform == Transform.Identity)
            {
                element.RenderTransform = new TranslateTransform(0, 20);
                element.RenderTransformOrigin = new Point(0.5, 0.5);
            }
        }

        private async Task AnimateCardAppearance(FrameworkElement element, int delay)
        {
            if (delay > 0)
            {
                await Task.Delay(delay);
            }

            var storyboard = new Storyboard();

            // 透明度动画 - 主要的加载效果
            var opacityAnimation = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(CARD_LOAD_DURATION))
            {
                EasingFunction = CardLoadEasing
            };
            Storyboard.SetTarget(opacityAnimation, element);
            Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath(UIElement.OpacityProperty));
            storyboard.Children.Add(opacityAnimation);

            // 轻微的位移动画 - 不影响卡片大小
            var translateTransform = element.RenderTransform as TranslateTransform;
            if (translateTransform != null)
            {
                var translateYAnimation = new DoubleAnimation(20, 0, TimeSpan.FromMilliseconds(CARD_LOAD_DURATION))
                {
                    EasingFunction = CardLoadEasing
                };
                Storyboard.SetTarget(translateYAnimation, translateTransform);
                Storyboard.SetTargetProperty(translateYAnimation, new PropertyPath(TranslateTransform.YProperty));
                storyboard.Children.Add(translateYAnimation);
            }

            var tcs = new TaskCompletionSource<bool>();
            storyboard.Completed += (s, e) => tcs.SetResult(true);

            storyboard.Begin();
            await tcs.Task;
        }

        #endregion

        #region 模式切换动画

        /// <summary>
        /// 模式切换动画 - 优雅的滑动过渡效果
        /// </summary>
        /// <param name="tabControl">目标TabControl</param>
        /// <param name="fromIndex">原索引</param>
        /// <param name="toIndex">目标索引</param>
        /// <returns>异步任务</returns>
        public async Task AnimateModeSwitchAsync(TabControl tabControl, int fromIndex, int toIndex)
        {
            if (tabControl == null) return;

            await tabControl.Dispatcher.InvokeAsync(async () =>
            {
                var fromTab = GetTabContent(tabControl, fromIndex);
                var toTab = GetTabContent(tabControl, toIndex);

                if (fromTab == null || toTab == null) return;

                // 准备动画
                var direction = toIndex > fromIndex ? 1 : -1;
                PrepareTabForSwitch(toTab, direction);

                // 创建滑动动画
                var storyboard = new Storyboard();

                // 旧标签页滑出
                var fromTranslateAnimation = new DoubleAnimation(0, -direction * 300, TimeSpan.FromMilliseconds(MODE_SWITCH_DURATION))
                {
                    EasingFunction = ModeSwitchEasing
                };
                var fromOpacityAnimation = new DoubleAnimation(1, 0, TimeSpan.FromMilliseconds(MODE_SWITCH_DURATION / 2))
                {
                    EasingFunction = ModeSwitchEasing
                };

                // 新标签页滑入
                var toTranslateAnimation = new DoubleAnimation(direction * 300, 0, TimeSpan.FromMilliseconds(MODE_SWITCH_DURATION))
                {
                    EasingFunction = ModeSwitchEasing
                };
                var toOpacityAnimation = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(MODE_SWITCH_DURATION))
                {
                    EasingFunction = ModeSwitchEasing,
                    BeginTime = TimeSpan.FromMilliseconds(MODE_SWITCH_DURATION / 4)
                };

                // 设置动画目标
                SetTabAnimationTargets(storyboard, fromTab, fromTranslateAnimation, fromOpacityAnimation);
                SetTabAnimationTargets(storyboard, toTab, toTranslateAnimation, toOpacityAnimation);

                var tcs = new TaskCompletionSource<bool>();
                storyboard.Completed += (s, e) => tcs.SetResult(true);

                storyboard.Begin();
                await tcs.Task;
            });
        }

        private FrameworkElement GetTabContent(TabControl tabControl, int index)
        {
            if (index < 0 || index >= tabControl.Items.Count) return null;
            
            var tabItem = tabControl.Items[index] as TabItem;
            return tabItem?.Content as FrameworkElement;
        }

        private void PrepareTabForSwitch(FrameworkElement tab, int direction)
        {
            tab.RenderTransform = new TranslateTransform(direction * 300, 0);
            tab.Opacity = 0;
        }

        private void SetTabAnimationTargets(Storyboard storyboard, FrameworkElement tab, 
            DoubleAnimation translateAnim, DoubleAnimation opacityAnim)
        {
            Storyboard.SetTarget(translateAnim, tab.RenderTransform);
            Storyboard.SetTargetProperty(translateAnim, new PropertyPath(TranslateTransform.XProperty));
            
            Storyboard.SetTarget(opacityAnim, tab);
            Storyboard.SetTargetProperty(opacityAnim, new PropertyPath(UIElement.OpacityProperty));

            storyboard.Children.Add(translateAnim);
            storyboard.Children.Add(opacityAnim);
        }

        #endregion

        #region 筛选器动画

        /// <summary>
        /// 筛选器下拉弹出动画 - 企业级展开效果
        /// </summary>
        /// <param name="comboBox">目标ComboBox</param>
        /// <returns>异步任务</returns>
        public async Task AnimateFilterPopupAsync(ComboBox comboBox)
        {
            if (comboBox == null) return;

            await comboBox.Dispatcher.InvokeAsync(() =>
            {
                // 为ComboBox添加打开动画
                comboBox.DropDownOpened += (s, e) =>
                {
                    AnimateFilterDropDown(comboBox, true);
                };

                comboBox.DropDownClosed += (s, e) =>
                {
                    AnimateFilterDropDown(comboBox, false);
                };
            });
        }

        private void AnimateFilterDropDown(ComboBox comboBox, bool isOpening)
        {
            try
            {
                // 查找ComboBox的Popup
                var popup = FindVisualChild<System.Windows.Controls.Primitives.Popup>(comboBox);
                if (popup?.Child is FrameworkElement popupChild)
                {
                    if (isOpening)
                    {
                        // 准备打开动画
                        var transformGroup = new TransformGroup();
                        transformGroup.Children.Add(new ScaleTransform(0.9, 0.8));
                        transformGroup.Children.Add(new TranslateTransform(0, -10));
                        popupChild.RenderTransform = transformGroup;
                        popupChild.RenderTransformOrigin = new Point(0.5, 0);
                        popupChild.Opacity = 0;

                        // 创建弹出动画
                        var storyboard = new Storyboard();

                        var opacityAnim = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(FILTER_POPUP_DURATION))
                        {
                            EasingFunction = FilterPopupEasing
                        };
                        Storyboard.SetTarget(opacityAnim, popupChild);
                        Storyboard.SetTargetProperty(opacityAnim, new PropertyPath(UIElement.OpacityProperty));
                        storyboard.Children.Add(opacityAnim);

                        // 简化的缩放动画
                        var scaleTransform = transformGroup.Children[0] as ScaleTransform;
                        if (scaleTransform != null)
                        {
                            var scaleXAnim = new DoubleAnimation(0.9, 1.0, TimeSpan.FromMilliseconds(FILTER_POPUP_DURATION))
                            {
                                EasingFunction = FilterPopupEasing
                            };
                            Storyboard.SetTarget(scaleXAnim, scaleTransform);
                            Storyboard.SetTargetProperty(scaleXAnim, new PropertyPath(ScaleTransform.ScaleXProperty));
                            storyboard.Children.Add(scaleXAnim);

                            var scaleYAnim = new DoubleAnimation(0.8, 1.0, TimeSpan.FromMilliseconds(FILTER_POPUP_DURATION))
                            {
                                EasingFunction = FilterPopupEasing
                            };
                            Storyboard.SetTarget(scaleYAnim, scaleTransform);
                            Storyboard.SetTargetProperty(scaleYAnim, new PropertyPath(ScaleTransform.ScaleYProperty));
                            storyboard.Children.Add(scaleYAnim);
                        }

                        storyboard.Begin();
                    }
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"筛选器动画异常: {ex.Message}");
            }
        }

        #endregion

        #region 加载状态动画

        /// <summary>
        /// 加载状态脉冲动画 - 优雅的呼吸效果
        /// </summary>
        /// <param name="element">目标元素</param>
        /// <param name="isLoading">是否开始加载</param>
        public void AnimateLoadingState(FrameworkElement element, bool isLoading)
        {
            if (element == null) return;

            element.Dispatcher.Invoke(() =>
            {
                if (isLoading)
                {
                    StartLoadingPulse(element);
                }
                else
                {
                    StopLoadingPulse(element);
                }
            });
        }

        private void StartLoadingPulse(FrameworkElement element)
        {
            var storyboard = new Storyboard
            {
                RepeatBehavior = RepeatBehavior.Forever
            };

            var pulseAnimation = new DoubleAnimation(0.6, 1.0, TimeSpan.FromMilliseconds(LOADING_PULSE_DURATION))
            {
                EasingFunction = new SineEase { EasingMode = EasingMode.EaseInOut },
                AutoReverse = true
            };

            Storyboard.SetTarget(pulseAnimation, element);
            Storyboard.SetTargetProperty(pulseAnimation, new PropertyPath(UIElement.OpacityProperty));
            storyboard.Children.Add(pulseAnimation);

            // 存储Storyboard以便后续停止
            element.Tag = storyboard;
            storyboard.Begin();
        }

        private void StopLoadingPulse(FrameworkElement element)
        {
            if (element.Tag is Storyboard storyboard)
            {
                storyboard.Stop();
                element.Tag = null;
                element.Opacity = 1.0; // 恢复正常透明度
            }
        }

        #endregion

        #region 按钮交互动画

        /// <summary>
        /// 按钮点击涟漪效果 - 企业级Material Design风格
        /// </summary>
        /// <param name="button">目标按钮</param>
        /// <param name="clickPoint">点击位置</param>
        public void AnimateButtonRipple(Button button, Point clickPoint)
        {
            if (button == null) return;

            button.Dispatcher.Invoke(() =>
            {
                // 创建涟漪效果
                var ripple = new Ellipse
                {
                    Fill = new SolidColorBrush(Colors.White) { Opacity = 0.3 },
                    Width = 0,
                    Height = 0,
                    RenderTransform = new TranslateTransform(clickPoint.X, clickPoint.Y)
                };

                // 添加到按钮的视觉树中
                if (button.Template?.FindName("PART_ContentHost", button) is Panel panel)
                {
                    panel.Children.Add(ripple);

                    // 计算涟漪的最大半径
                    var maxRadius = Math.Max(button.ActualWidth, button.ActualHeight) * 1.5;

                    // 创建涟漪动画
                    var storyboard = new Storyboard();

                    var sizeAnimation = new DoubleAnimation(0, maxRadius, TimeSpan.FromMilliseconds(400))
                    {
                        EasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseOut }
                    };

                    var opacityAnimation = new DoubleAnimation(0.3, 0, TimeSpan.FromMilliseconds(600))
                    {
                        BeginTime = TimeSpan.FromMilliseconds(100)
                    };

                    Storyboard.SetTarget(sizeAnimation, ripple);
                    Storyboard.SetTargetProperty(sizeAnimation, new PropertyPath(FrameworkElement.WidthProperty));

                    var sizeAnimation2 = sizeAnimation.Clone();
                    Storyboard.SetTarget(sizeAnimation2, ripple);
                    Storyboard.SetTargetProperty(sizeAnimation2, new PropertyPath(FrameworkElement.HeightProperty));

                    Storyboard.SetTarget(opacityAnimation, ripple.Fill);
                    Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath(Brush.OpacityProperty));

                    storyboard.Children.Add(sizeAnimation);
                    storyboard.Children.Add(sizeAnimation2);
                    storyboard.Children.Add(opacityAnimation);

                    storyboard.Completed += (s, e) => panel.Children.Remove(ripple);
                    storyboard.Begin();
                }
            });
        }

        #endregion

        #region 辅助方法

        /// <summary>
        /// 查找可视化树中的子元素
        /// </summary>
        private T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
            {
                var child = VisualTreeHelper.GetChild(parent, i);
                if (child is T found)
                    return found;

                var childOfChild = FindVisualChild<T>(child);
                if (childOfChild != null)
                    return childOfChild;
            }
            return null;
        }

        /// <summary>
        /// 重置所有动画效果
        /// </summary>
        public void ResetAllAnimations(FrameworkElement element)
        {
            if (element == null) return;

            element.Dispatcher.Invoke(() =>
            {
                element.RenderTransform = Transform.Identity;
                element.Opacity = 1.0;
                
                if (element.Tag is Storyboard storyboard)
                {
                    storyboard.Stop();
                    element.Tag = null;
                }
            });
        }

        #endregion
    }
}
